package com.sinochem.yunlian.ship.base.rpc;

import com.alibaba.fastjson.JSONObject;
import com.sinochem.yunlian.ship.api.vo.bs.*;
import com.sinochem.yunlian.ship.base.biz.*;
import com.sinochem.yunlian.ship.base.entity.*;
import com.sinochem.yunlian.ship.base.vo.response.DictItemVo;
import com.sinochem.yunlian.ship.base.vo.response.MaterialCategoryVo;
import com.sinochem.yunlian.ship.common.annotation.IgnoreToken;
import com.sinochem.yunlian.ship.common.constant.DataDictCode;
import com.sinochem.yunlian.ship.common.constant.RedisKey;
import com.sinochem.yunlian.ship.common.enums.PortType;
import com.sinochem.yunlian.ship.common.enums.ResponseCode;
import com.sinochem.yunlian.ship.common.msg.RestResponse;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("api")
@IgnoreToken
public class BaseInfoRest {

    /**
     * 非必填节点
     */
    public static final int NOT_REQUIRED_NODE = 0;
    /**
     * 必填节点
     */
    public static final int REQUIRED_NODE = 1;

    @Autowired
    private BsPortBiz bsPortBiz;

    @Autowired
    private BsMaterialCategoryBiz bsMaterialCategoryBiz;
    @Autowired
    private BsNodeBiz  bsNodeBiz;

    @Autowired
    private BsDataDictItemBiz bsDataDictItemBiz;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private BsExceptionInfoBiz exceptionInfoBiz;

    /**
     * 根据portId获取港口信息
     *
     * */
    @RequestMapping(value = "/base/port/getPortById/{portId}", method = RequestMethod.GET)
    public PortVO getPortNameById(@PathVariable("portId") String portId) {
        if (redisTemplate.hasKey(RedisKey.KEY_PORT_MAP)) {
            Map<String,PortVO> resultMap = redisTemplate.opsForHash().entries(RedisKey.KEY_PORT_MAP);
            return resultMap.get(portId);
        } else {
            List<BsPort> list = bsPortBiz.findAllPorts();
            Map<String,PortVO> portMap = new HashMap<>(list.size());
            for (BsPort port : list) {
                PortVO vo = new PortVO();
                vo.setId(port.getId());
                vo.setLat(port.getLat());
                vo.setLon(port.getLon());
                vo.setLevel(port.getLevel());
                vo.setParentId(port.getParentId());
                vo.setPortName(port.getPortName());
                vo.setPortCode(port.getPortCode());
                vo.setShortName(port.getShortName());
                portMap.put(vo.getId()+"",vo);
            }
            redisTemplate.opsForHash().putAll(RedisKey.KEY_PORT_MAP,portMap);
            return portMap.get(portId);
        }
    }

    /**
     * 根据货品种类id获取MaterialCategory
     * */
    @RequestMapping(value = "/base/materialCategory/getCategoryByIds", method = RequestMethod.GET)
    public List<MaterialCategoryVO> getCategoryByIds(@RequestParam("categoryIds") String categoryIds) {

        List<MaterialCategoryVO> materialCategoryVOs = new ArrayList<>();
        String[] ids = categoryIds.split(",");
        if (redisTemplate.hasKey(RedisKey.KEY_MATERIAL_CATEGORY_MAP)) {
            for (String id : ids) {
                Map<String,MaterialCategoryVO> resultMap = redisTemplate.opsForHash().entries(RedisKey.KEY_MATERIAL_CATEGORY_MAP);
                materialCategoryVOs.add(resultMap.get(id));
            }
            return materialCategoryVOs;
        } else {
            List<BsMaterialCategory> list = bsMaterialCategoryBiz.findAllMaterialCategory();
            Map<String,MaterialCategoryVO> portMap = new HashMap<>(list.size());
            for (BsMaterialCategory category : list) {
                MaterialCategoryVO vo = new MaterialCategoryVO();
                vo.setId(category.getId());
                vo.setCategoryName(category.getCategoryName());
                vo.setEnName(category.getEnName());
                vo.setGroupId(category.getGroupId());
                vo.setLevel(category.getLevel());
                portMap.put(vo.getId()+"",vo);
            }
            redisTemplate.opsForHash().putAll(RedisKey.KEY_MATERIAL_CATEGORY_MAP,portMap);
            for (String id : ids) {
                if(portMap.get(id) !=null) {
                    materialCategoryVOs.add(portMap.get(id));
                }
            }
            return materialCategoryVOs;
        }
    }


    /**
     * 根据货品种类id获取MaterialCategory
     * */
    @RequestMapping(value = "/base/materialCategory/getCategoryById/{categoryId}", method = RequestMethod.GET)
    public MaterialCategoryVO getCategoryById(@PathVariable("categoryId") String categoryId) {

        if (redisTemplate.hasKey(RedisKey.KEY_MATERIAL_CATEGORY_MAP)) {
            Map<String,MaterialCategoryVO> resultMap = redisTemplate.opsForHash().entries(RedisKey.KEY_MATERIAL_CATEGORY_MAP);
            return resultMap.get(categoryId);
        } else {
            List<BsMaterialCategory> list = bsMaterialCategoryBiz.findAllMaterialCategory();
            Map<String,MaterialCategoryVO> portMap = new HashMap<>(list.size());
            for (BsMaterialCategory category : list) {
                MaterialCategoryVO vo = new MaterialCategoryVO();
                vo.setId(category.getId());
                vo.setCategoryName(category.getCategoryName());
                vo.setEnName(category.getEnName());
                vo.setGroupId(category.getGroupId());
                vo.setLevel(category.getLevel());
                portMap.put(vo.getId()+"",vo);
            }
            redisTemplate.opsForHash().putAll(RedisKey.KEY_MATERIAL_CATEGORY_MAP,portMap);
            return portMap.get(categoryId);
        }
    }

    /**
     * 根据港口类型获取所有必填的nodeIds
     * */
    @RequestMapping(value = "/base/nodes/getRequiredNodes", method = RequestMethod.GET)
    public List<BsNodeVO> getRequiredNodes(@RequestParam("nodeType") String nodeType) {
        Integer _nodeType = null;
        if(StringUtils.isNotBlank(nodeType)){
            _nodeType = new Integer(nodeType);
        }
        if(nodeType.equals(PortType.FROM_PORT.getCode() + "")){
            return getBsNodeVOS(true,_nodeType,RedisKey.REQUIRED_KEY_NODE_FROM);
        }else if(nodeType.equals(PortType.TO_PORT.getCode() + "")){
            return getBsNodeVOS(true,_nodeType,RedisKey.REQUIRED_KEY_NODE_TO);
        }else{
            return getBsNodeVOS(true,null,RedisKey.REQUIRED_KEY_NODE_ALL);
        }
    }




    /**
     * 根据 itemValue获取值
     * */
    @RequestMapping(value = "/base/dict/getDictItemByValue", method = RequestMethod.GET)
    public DictItemVo getDictItemByValue(@RequestParam String dictCode,@RequestParam Integer itemValue) {
        DictItemVo dictItem = null;
        String key = String.format(RedisKey.KEY_DICT_ITEM_MAP_PREFIX,dictCode);
        if (redisTemplate.hasKey(key)) {
            Map<String,DictItemVo> itemMap = redisTemplate.opsForHash().entries(key);
            return itemMap.get(itemValue);
        } else {
            List<BsDataDictItem> list = bsDataDictItemBiz.findByDictCodeForView(dictCode);
            Map<String,DictItemVo> dictMap = new HashMap<>(list.size());
            for (BsDataDictItem item : list) {
                DictItemVo vo = new DictItemVo();
                vo.setId(item.getId());
                vo.setDictCode(item.getDictCode());
                vo.setDictId(item.getDictId());
                vo.setItemCode(item.getItemCode());
                vo.setItemName(item.getItemName());
                vo.setItemValue(item.getItemValue());
                vo.setShowOrder(item.getShowOrder());
                dictMap.put(vo.getItemValue()+"",vo);
            }
            redisTemplate.opsForHash().putAll(key,dictMap);
            return dictMap.get(itemValue);
        }

    }

    /**
     * 根据 dictCode 获取 itemCode,itemName
     * */
    @RequestMapping(value = "/base/dict/getDictItemMapByCode", method = RequestMethod.GET)
    public Map<String,DictItemVo> getDictItemMapByCode(@RequestParam String dictCode) {
        Map<String,DictItemVo> itemMap = null;
        String key = String.format(RedisKey.KEY_DICT_ITEM_MAP_PREFIX,dictCode);
        if (redisTemplate.hasKey(key)) {
            itemMap = redisTemplate.opsForHash().entries(key);
            return itemMap;
        } else {
            List<BsDataDictItem> list = bsDataDictItemBiz.findByDictCodeForView(dictCode);
            Map<String,DictItemVo> dictMap = new HashMap<>(list.size());
            for (BsDataDictItem item : list) {
                DictItemVo vo = new DictItemVo();
                vo.setId(item.getId());
                vo.setDictCode(item.getDictCode());
                vo.setDictId(item.getDictId());
                vo.setItemCode(item.getItemCode());
                vo.setItemName(item.getItemName());
                vo.setItemValue(item.getItemValue());
                vo.setShowOrder(item.getShowOrder());
                dictMap.put(vo.getItemValue()+"",vo);
            }
            redisTemplate.opsForHash().putAll(key,dictMap);
            itemMap = dictMap;
        }
        return itemMap;

    }



    @RequestMapping(value = "/base/nodes/allNodeItems",method = RequestMethod.GET)
    public List<NodeItemsVo> getAllNodeItems(){
        String key = RedisKey.KEY_DIC_ALL_ITEM;
        if (redisTemplate.hasKey(key)) {
            String nodeItmes = (String) redisTemplate.boundValueOps(key).get();
            List<NodeItemsVo> nodesItem = JSONObject.parseArray(nodeItmes,NodeItemsVo.class);

            return nodesItem;
        } else {
            List<NodeItemsVo> itemsVos = new ArrayList<>();
            List<BsNodeItem> nodesItem = bsNodeBiz.findAllNodeItems();
            for(BsNodeItem item:nodesItem){
                NodeItemsVo vo = new NodeItemsVo();
                BeanUtils.copyProperties(item,vo);
                itemsVos.add(vo);
            }
            String itemStr = JSONObject.toJSONString(itemsVos);
            BoundValueOperations valueOperations =redisTemplate.boundValueOps(key);
            valueOperations.set(itemStr);
            return itemsVos;
        }

    }

    /**
     * 根据节点id获取nodeInfo
     * */
    @RequestMapping(value = "/base/nodes/getNodeInfoById", method = RequestMethod.GET)
    public BsNodeVO getNodeById(@RequestParam String nodeId) {
        if (redisTemplate.hasKey(RedisKey.KEY_NODE_MAP)) {
            Map<String,BsNodeVO> resultMap = redisTemplate.opsForHash().entries(RedisKey.KEY_NODE_MAP);
            BsNodeVO  nodeVO = resultMap.get(nodeId);
            return resultMap.get(nodeId);
        } else {
            List<BsNode> list = bsNodeBiz.findAllNodes();
            Map<String,BsNodeVO> portMap = new HashMap<>(list.size());
            for (BsNode bsNode : list) {
                BsNodeVO vo = new BsNodeVO();
                BeanUtils.copyProperties(bsNode,vo);
                portMap.put(vo.getId()+"",vo);
            }
            redisTemplate.opsForHash().putAll(RedisKey.KEY_NODE_MAP,portMap);
            return portMap.get(nodeId);
        }
    }

    /**
     * 节点列表：
     *  portType  0 装货港  1 卸货港
     * @return
     */
    @RequestMapping(value = "/base/nodes/getNodeListByPortType",method = RequestMethod.GET)
    public List<BsNodeVO> getNodeListByPortType(@RequestParam("portType") Integer portType){
        String redisKey = null;
        List<BsNodeVO>  bsNodeVOS = null;
        if(portType.intValue() == PortType.FROM_PORT.getCode()){
                bsNodeVOS =  getBsNodeVOS(portType,RedisKey.KEY_NODE_FROM);
        }else if(portType.intValue() == PortType.TO_PORT.getCode()){
                bsNodeVOS =  getBsNodeVOS(portType,RedisKey.KEY_NODE_TO);
        }
        return bsNodeVOS;
    }

    private List<BsNodeVO> getBsNodeVOS(Integer nodeType,String redisKey) {
        if (redisTemplate.hasKey(redisKey)) {
            String needNodes = (String) redisTemplate.boundValueOps(redisKey).get();
            List<BsNodeVO> nodes = JSONObject.parseArray(needNodes,BsNodeVO.class);
            return nodes;
        } else {
            List<BsNode> nodes = bsNodeBiz.findAllNodesByType(nodeType);
            List<BsNodeVO> bsNodeVOS = new ArrayList<>();
            for(BsNode bsNode : nodes){
                BsNodeVO bsNodeVO = new BsNodeVO();
                BeanUtils.copyProperties(bsNode,bsNodeVO);
                bsNodeVOS.add(bsNodeVO);
            }
            String needNodes = JSONObject.toJSONString(bsNodeVOS);
            BoundValueOperations valueOperations =redisTemplate.boundValueOps(redisKey);
            valueOperations.set(needNodes);
            return bsNodeVOS;
        }
    }



    /**
     * 节点列表：
     *
     *  required  0 非必填  1 必填
     *  portType  0 装货港  1 卸货港 不传港口类型，则查询全部
     * @return
     */
    @RequestMapping(value = "/base/nodes/getNodesByCondition",method = RequestMethod.GET)
    public List<BsNodeVO> getNodeList(@RequestParam("required") Integer required,@RequestParam("portType") Integer portType){
        boolean requiredFlag = required.intValue() == REQUIRED_NODE ? true : false;
        String redisKey = null;
        List<BsNodeVO>  bsNodeVOS = null;
        if(required.intValue() == NOT_REQUIRED_NODE){
            if(portType == null){
                bsNodeVOS =  getBsNodeVOS(requiredFlag, portType,RedisKey.NOT_REQUIRED_KEY_NODE_ALL);
            }else if(portType.intValue() == PortType.FROM_PORT.getCode()){
                bsNodeVOS =  getBsNodeVOS(requiredFlag, portType,RedisKey.NOT_REQUIRED_KEY_NODE_FORM);
            }else {
                bsNodeVOS =  getBsNodeVOS(requiredFlag, portType,RedisKey.NOT_REQUIRED_KEY_NODE_TO);
            }
        }else{
            if(portType == null){
                bsNodeVOS =  getBsNodeVOS(requiredFlag, portType,RedisKey.REQUIRED_KEY_NODE_ALL);
            }else if(portType.intValue() == PortType.FROM_PORT.getCode()){
                bsNodeVOS =  getBsNodeVOS(requiredFlag, portType,RedisKey.REQUIRED_KEY_NODE_FROM);
            }else {
                bsNodeVOS =  getBsNodeVOS(requiredFlag, portType,RedisKey.REQUIRED_KEY_NODE_TO);
            }
        }
        return bsNodeVOS;
    }

    private List<BsNodeVO> getBsNodeVOS(boolean isRequired,Integer portType, String redisKey) {
        if (redisTemplate.hasKey(redisKey)) {
            String needNodes = (String) redisTemplate.boundValueOps(redisKey).get();
            List<BsNodeVO> nodes = JSONObject.parseArray(needNodes,BsNodeVO.class);
            return nodes;
        }
        if(isRequired){
            List<BsNode> nodes = bsNodeBiz.findAllRequiredNodes(portType);
            List<BsNodeVO> bsNodeVOS = new ArrayList<>();
            for(BsNode bsNode : nodes){
                BsNodeVO bsNodeVO = new BsNodeVO();
                BeanUtils.copyProperties(bsNode,bsNodeVO);
                bsNodeVOS.add(bsNodeVO);
            }
            String needNodes = JSONObject.toJSONString(bsNodeVOS);
            BoundValueOperations valueOperations =redisTemplate.boundValueOps(redisKey);
            valueOperations.set(needNodes);
            return bsNodeVOS;
        }else{
            List<BsNode> nodes = bsNodeBiz.findAllNotRequiredNodes(portType);
            List<BsNodeVO> bsNodeVOS = new ArrayList<>();
            for(BsNode bsNode : nodes){
                BsNodeVO bsNodeVO = new BsNodeVO();
                BeanUtils.copyProperties(bsNode,bsNodeVO);
                bsNodeVOS.add(bsNodeVO);
            }
            String needNodes = JSONObject.toJSONString(bsNodeVOS);
            BoundValueOperations valueOperations =redisTemplate.boundValueOps(redisKey);
            valueOperations.set(needNodes);
            return bsNodeVOS;
        }
    }



    @RequestMapping(value = "/base/except/exceptionInfo",method = RequestMethod.GET)
    public List<BsExceptionInfoVo> getAllExceptionInfo(){
        String key = RedisKey.KEY_DIC_ALL_Exception;
        if (redisTemplate.hasKey(key)) {
            String exInfo = (String) redisTemplate.boundValueOps(key).get();
            List<BsExceptionInfoVo> exceptionInfoVoList = JSONObject.parseArray(exInfo,BsExceptionInfoVo.class);
            return exceptionInfoVoList;
        } else {
            List<BsExceptionInfoVo> exVos = new ArrayList<>();
            List<BsExceptionInfo> exceptionInfo = exceptionInfoBiz.getAllExceptionInfo(0);
            for(BsExceptionInfo item:exceptionInfo){
                BsExceptionInfoVo vo = new BsExceptionInfoVo();
                BeanUtils.copyProperties(item,vo);
                exVos.add(vo);
            }
            String exStr = JSONObject.toJSONString(exVos);
            BoundValueOperations valueOperations =redisTemplate.boundValueOps(key);
            valueOperations.set(exStr);
            return exVos;
        }

    }

    @RequestMapping(value = "/dict/findDictItemByCode",method = RequestMethod.POST)
    public  Map<String,Object> findDictItemByCode(@RequestBody Map params) {
        String dictCodes = params.get("dictCodes")+"";
        Map reMap = new HashMap();
        List<BsDataDictItem> items = bsDataDictItemBiz.findByDictCodeForView(dictCodes);
        for (BsDataDictItem item : items) {
            reMap.put(item.getItemCode(),item.getItemValue());
        }
        return reMap;
    }




}
